//////////////////////////////////////////////
// DeflateEncoder.h
//
//////////////////////////////////////////////

/// Defines / Macros -------------------------

#pragma once

/// Includes ---------------------------------

// nkMemory
#include "../Dll/DllDefines.h"

#include "../Containers/Buffer.h"
#include "../Containers/BufferView.h"

#include "../Streams/BitStream.h"

#include "HuffmanLut.h"

/// Internals --------------------------------

namespace nkMemory
{
	enum class DEFLATE_BLOCK_TYPE
	{
		RAW = 0b00,
		STATIC_HUFFMAN = 0b01,
		DYNAMIC_HUFFMAN = 0b10
	} ;

	struct DeflateOutputStorage final
	{
		nkMemory::BufferView<> _output ;
		unsigned int _currentByte = 0u ;
	} ;
}

/// Class ------------------------------------

namespace nkMemory
{
	class DLL_MEMORY_EXPORT DeflateEncoder
	{
		public :

			// Constructor, destructor
			DeflateEncoder () noexcept ;
			DeflateEncoder (BitStream data) noexcept ;
			DeflateEncoder (BufferView<> data) noexcept ;

			// Setters
			void setDataStream (BitStream data) ;
			void setTransientOutput (BufferView<> output) ;

			// Decompression
			BufferView<> decode () ;
			BufferView<> decode (BufferView<> output) ;
			bool isDecodingDone () const ;

		private :

			// Decompression status
			BitStream _data ;
			DeflateOutputStorage _output ;
			
			HuffmanLut _literalHuffman ;
			HuffmanLut _distanceHuffman ;
			BufferView<const HuffmanSymbol> _literalHuffmanLut ;
			BufferView<const HuffmanSymbol> _distanceHuffmanLut ;
			DEFLATE_BLOCK_TYPE _currentBlockType ;
			unsigned int _rawCounter ;
			unsigned int _rawSize ;

			bool _ongoingBlock ;
			bool _decodingDone ;
	} ;
}